package com.linkstec.wechat;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
//import java.util.concurrent.TimeUnit;
import java.util.concurrent.CountDownLatch;

//import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.concurrent.FutureCallback;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager;
import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
import org.apache.http.impl.nio.reactor.IOReactorConfig;
import org.apache.http.nio.reactor.ConnectingIOReactor;
import org.apache.http.nio.reactor.IOReactorException;
import org.apache.http.util.EntityUtils;

import com.alibaba.fastjson.JSON;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class WechatHttpClient {

    static CloseableHttpAsyncClient client = null;
    static StringEntity entity = null;

    // 基础支持: 获取access_token接口 /token
    // https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx6b3ad2326a8f29a3&secret=f53087558de4c98cfd4be8b926c2ec1a
    public static void main(String[] args) {


        Map<String, String> map = new HashMap<String, String>();
        map.put("data2", LocalDateTime.now().toString());
        map.put("data3", "1000万");
        sendWechat(map);

        // 构造请求
        /*
         * String geturl = "https://www.baidu.com"; HttpGet httpGet = new
         * HttpGet(geturl); long start = System.currentTimeMillis(); for (int i =
         * 0;i<1;i++) { doGet(client, httpGet); }
         * System.out.println(" cost is:"+(System.currentTimeMillis()-start));
         */

        /*
         * while(true){ try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException
         * e) { e.printStackTrace(); } }
         */
    }

    public static void sendWechat(Map<String, String> map) {

        String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=";
        String access_token = "70_AGnrweI5m66knHhnar2OrxT6O2fg0mPvVjbS0OAh1CaMDRjMllJdPYAdlLR7BA9JJ8MpdDFDaH_y24wd_5HVFEAoEMgjrFQsZZ08FW-EhKyOlrg7ymICb1PEnrARCPaAAAYJW";
        url = url + access_token;

        CloseableHttpAsyncClient client = getClient();

        CountDownLatch countDownLatch = new CountDownLatch(1);
        // start
        client.start();
        post(client, url, map, countDownLatch);
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            log.error("", e);
        } finally {
            try {
                client.close();
            } catch (IOException e) {
                log.error("", e);
            }
        }
    }

    public static HttpPost getHttpPost(String url) {
        // 构造请求
        String urlPost = url;
        HttpPost httpPost = new HttpPost(urlPost);
        httpPost.setHeader("Content-Type", "application/json;encoding=utf-8");

        return httpPost;
    }

    public static CloseableHttpAsyncClient getClient() {
        // 设置代理IP、端口、协议（请分别替换）
//		HttpHost proxy = new HttpHost("172.16.0.1", 3128, "http");

        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(50000).setSocketTimeout(50000)
                .setConnectionRequestTimeout(1000)
//				.setProxy(proxy)
                .build();

        // 配置io线程
        IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
                .setIoThreadCount(Runtime.getRuntime().availableProcessors()).setSoKeepAlive(true).build();
        // 设置连接池大小
        ConnectingIOReactor ioReactor = null;
        try {
            ioReactor = new DefaultConnectingIOReactor(ioReactorConfig);
        } catch (IOReactorException e) {
            e.printStackTrace();
        }
        PoolingNHttpClientConnectionManager connManager = new PoolingNHttpClientConnectionManager(ioReactor);
        connManager.setMaxTotal(100);
        connManager.setDefaultMaxPerRoute(100);

        client = HttpAsyncClients.custom().setConnectionManager(connManager).setDefaultRequestConfig(requestConfig)
                .build();

        return client;
    }

    public static StringEntity getEntity(Map<String, String> map) {

        try {
            HashMap<String, Object> postMap = new HashMap<String, Object>();
            postMap.put("touser", "o37K856Qlp8ZfgN2n4aCjpL4yFXI");
            // postMap.put("touser", "ooD9m526deYDP2qAfe5ex6ec5TVU");
            // postMap.put("touser", "ooD9m5xIglSlMEFKPAThmUK2XgRs");
            // postMap.put("template_id", "D6NxyvbgcAhAFFRxVvzN0zD0oshfIm5QXV30tLMMfAs");
            // postMap.put("template_id", "_unqYW7B07PM112l0lSewlCU2V3lFsnMRDE8yRNjIBs");
            postMap.put("template_id", "3xTBTj_2seGBS5g9v_CAHxtEGfe_itglaiF4DQQRuzA");
            // postMap.put("url", "http://weixin.qq.com/download");
            postMap.put("url", "http://www.baidu.com");
            postMap.put("topcolor", "#FF0000");
            postMap.put("emphasis_keyword", "orderid.DATA");
            HashMap<String, Object> data = new HashMap<String, Object>();
            HashMap<String, String> data1 = new HashMap<String, String>();
            data1.put("value", "您有新的转账，请注意查收");
            data1.put("color", "#173177");
            data.put("first", data1);
            HashMap<String, String> data2 = new HashMap<String, String>();
//			data2.put("value", "20190612111");
            data2.put("value", map.get("data2"));
            data2.put("color", "#173177");
            data.put("orderid", data2);
            HashMap<String, String> data3 = new HashMap<String, String>();
//			data3.put("value", "1000万");
            data3.put("value", map.get("data3"));
            data3.put("color", "#173177");
            data.put("amount", data3);
            HashMap<String, String> data4 = new HashMap<String, String>();
            data4.put("value", "如非本人操作，请注意风险哦。\n如有疑问，请资讯在线客服或致电188123456789\n地址：上海\n\n回复TD可退订此消息");
            data4.put("color", "#F7BA0B");
            data.put("remark", data4);
            postMap.put("data", data);

            String a = new String(JSON.toJSONString(postMap));
            System.out.println(a);
            // entity = new StringEntity(a);//中文乱码
            entity = new StringEntity(a, "UTF-8");
            entity.setContentType("application/json; charset=utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return entity;
    }

    public static void post(CloseableHttpAsyncClient client, String url, Map<String, String> map,
            CountDownLatch countDownLatch) {

        HttpPost httpPost = getHttpPost(url);
        StringEntity entity = getEntity(map);
        httpPost.setEntity(entity);

        // 异步请求
        client.execute(httpPost, new Back(countDownLatch));
    }

    public static void doGet(CloseableHttpAsyncClient client, String url, CountDownLatch countDownLatch) {

        HttpGet httpGet = new HttpGet(url);
        // 异步请求
        client.execute(httpGet, new Back(countDownLatch));

    }

    static class Back implements FutureCallback<HttpResponse> {

        private long start = System.currentTimeMillis();
        private CountDownLatch countDownLatch;

        Back(CountDownLatch countDownLatch) {
            this.countDownLatch = countDownLatch;
        }

        @Override
        public void completed(HttpResponse httpResponse) {
            try {
                log.info("cost is:" + (System.currentTimeMillis() - start) + ":"
                        + EntityUtils.toString(httpResponse.getEntity()));
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                countDownLatch.countDown();
            }
        }

        @Override
        public void failed(Exception e) {
            countDownLatch.countDown();
            log.error("错误 cost is:" + (System.currentTimeMillis() - start) + ":" + e);
        }

        @Override
        public void cancelled() {
            countDownLatch.countDown();

        }
    }
}